package utils.query;

import com.google.gson.annotations.Expose;
import org.apache.commons.lang.math.NumberUtils;
import play.db.jpa.Model;
import play.mvc.Http;
import play.templates.JavaExtensions;

import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by FireFire on 3/20 0020.
 * 分页辅助
 */
public class Page<T extends Model> {
    public static int DEFAULT_PAGESIZE = 6;
    //总记录数
    @Expose
    public int totalCount;

    //每页记录数
    @Expose
    public int pageSize;

    //总页数
    @Expose
    public int totalPage;

    //当前页数
    @Expose
    public int currPage;

    //列表数据
    @Expose
    public List<T> list;

    // 开始条数
    @Expose
    public int from;

    // 结束条数
    @Expose
    public int to ;

    public Page(){

    }

    /**
     * 获取RequestHeader中的分页数据，如下例
     * Range： items=25-49
     * Jquery设置Header的方法 ： $.ajax({beforesend:function(xhr){xhr.setRequestHeader('X-Test-Header', 'test-value');}});
     * @param headers
     * @return
     */
    private static Page getPageFromHeader(final Map<String, Http.Header> headers) {
        Page pager;
        if(headers.containsKey("range")) {
            String range = (String)headers.get("range").value();
            pager = new Page(range);
        } else {
            pager = new Page();
        }
        return pager;
    }

    private Page(String rawString) {
        Pattern pattern = Pattern.compile("^items=(\\d+)-(\\d+)(/(\\d+))?$");
        Matcher matcher = pattern.matcher(rawString);

        if(matcher.matches()) {
            int a = Integer.parseInt(matcher.group(1));
            int b = Integer.parseInt(matcher.group(2));

            String totalString = matcher.group(4);
            if(totalString != null && totalString.length() > 0) {
                this.totalCount = Integer.parseInt(matcher.group(4));
            }

            this.from = Math.min(a, b);
            this.to = Math.max(a, b);
        } else {
            throw new RuntimeException("not a valid Range header string");
        }
    }
    private static Page getPage(){
        return getPageFromRequest();
    }

    private static Page getPageFromRequest() {
        String pageSize = Http.Request.current().params.get("limit"); // 每页最大条数
        String page = Http.Request.current().params.get("page"); // 需要获取的页码
        Page pager = new Page();
        pager.pageSize = NumberUtils.toInt(pageSize);
        if(pager.pageSize<=0) pager.pageSize = DEFAULT_PAGESIZE;
        pager.currPage = NumberUtils.toInt(page);
        if(pager.currPage<=0) pager.currPage =1 ;
        pager.from = (pager.currPage-1)*pager.pageSize;
        pager.to = pager.from + pager.pageSize-1;
        return pager;
    }

    public static<T extends Model> Page getPageResults(ModelQuery<T> query){
        Page page = Page.getPage();
        page.totalCount = query.count();
        page.resetPageSize(page.from,page.to,page.totalCount);
        page.list = query.getResults(page.from,page.pageSize);
        return page;
    }

    private void resetPageSize(int from, int to, int totalCount){
        this.from = from;
        if(to<=0){
            to=DEFAULT_PAGESIZE-1;
        }
        if(totalCount<to) {
            to = totalCount-1;
        }
        this.to = to;
        this.totalPage = JavaExtensions.page(this.totalCount,this.pageSize);
    }

    public String toString() {
        return String.format("items=%d-%d%s", from, to, totalCount == -1 ? "" : "/" + String.valueOf(totalCount));
    }
}
